/* 
 * Copyright [2018] [Alex/libo(liboware@gmail.com)]
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hyts.properties.manager;

import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

import com.hyts.properties.base.PropertyBean;
import com.hyts.properties.bean.SinglePropertyBean;
import com.hyts.properties.config.PropertyConfiguration;

/** 
 * @author LiBo/Alex
 * @version V1.0 
 */
public final class PropertyManager {
    
    /**  
     * @fieldName propertyCachePool
     * @fieldType ConcurrentHashMap<String,PropertyBean<?>>
     */ 
    private ConcurrentHashMap<String, PropertyBean<?,?>> propertyCachePool;
    
    /**  
     * @fieldName manager
     * @fieldType PropertyManager
     */ 
    private static PropertyManager manager = null;
    
    /**  
     */
    private PropertyManager() {
        super();
        this.propertyCachePool = new ConcurrentHashMap<String,PropertyBean<?,?>>();
    }
    
    /**
     * 单例实例
     * @return
     * @exception
     */ 
    public static PropertyManager getInstance() {
        if(Objects.isNull(manager)) {
            synchronized(PropertyManager.class) {
                if(Objects.isNull(manager)) {
                    manager = new PropertyManager();
                }
            }
        }
        return manager;
    }

    /**
     * 创建新实例
     * @return
     */
    public static PropertyManager newInstance(){
        manager = new PropertyManager();
        return manager;
    }

    /**  
     * @name propertyCachePool's getter method
     * @return propertyCachePool
     */
    public ConcurrentHashMap<String, PropertyBean<?,?>> getPropertyCachePool() {
        return propertyCachePool;
    }
    
    
    /**  
     * @param configFileName
     * @return
     * @exception
     */ 
    public PropertyBean<?,?> get(String configFileName){
        return getPropertyCachePool().get(configFileName);
    }

    /**  
     * @param key
     * @return
     * @exception
     */ 
    public Object getValue(String key){
        return getValue(PropertyConfiguration.DEFAULT_PROPERTIES_FILE_PATH,PropertyConfiguration.DEFAULT_PROPERTIES_FILE_NAME,key);
    }

    /**
     * @param key
     * @return
     * @exception
     */
    public String getValue2Text(String key){
        return getValue2Text(key,null);
    }

    /**
     * @param key
     * @param defaultValue
     * @return
     */
    public String getValue2Text(String key,String defaultValue){
        Object value = getValue(key);
        return value == null ? defaultValue : value.toString();
    }


    /**
     * @param key
     * @return
     * @exception
     */
    public Integer getValue2Number(String key){
        return getValue2Number(key,null);
    }

    /**
     * @param key
     * @param defaultValue
     * @return
     */
    public Integer getValue2Number(String key,Integer defaultValue){
        Object value = getValue(key);
        return value == null ? defaultValue : Integer.parseInt(value.toString());
    }

    /**  
     * @param configFileName
     * @param key
     * @return
     * @exception
     */ 
    public Object getValue(String configFileName,String key){
        return getValue(PropertyConfiguration.DEFAULT_PROPERTIES_FILE_PATH,configFileName,key);
    }
    
    /**  
     * @param configFileName
     * @param configFilePath
     * @param key
     * @return
     * @exception
     */ 
    public Object getValue(String configFilePath,String configFileName,String key){
    	PropertyBean<?,?> obj = get(configFileName);
        if(Objects.isNull(obj)) {
            SinglePropertyBean bean = new SinglePropertyBean(configFilePath,configFileName).load();
            getPropertyCachePool().put(configFileName,bean);
            obj = bean;
        }
        synchronized(this) {
        	return obj.get(key);
        }
    }
    
    /**  
     * @param configFileName
     * @param key
     * @return
     * @exception
     */ 
    public Object getValue(String[] configFileName,String key){
      /*  PropertyBean<?> obj = get(configFileName);
        if(Objects.nonNull(obj))
            return obj.get(key);
        getPropertyCachePool().put(configFileName, new );
       */
        return null;
    }
    
    /**  
     * @param key
     * @param value
     * @return
     * @exception
     */ 
    public boolean setValue(String key,Object value){
        return setValue(PropertyConfiguration.DEFAULT_PROPERTIES_FILE_PATH,PropertyConfiguration.DEFAULT_PROPERTIES_FILE_NAME,key, value);
    }
    
    /**  
     * @param configFileName
     * @param key
     * @param value
     * @return
     * @exception
     */ 
    public boolean setValue(String configFileName,String key,Object value){
        return setValue(PropertyConfiguration.DEFAULT_PROPERTIES_FILE_PATH,configFileName,key, value);
    }
    
    /**  
     * @param configFilePath
     * @param configFileName
     * @param key
     * @param value
     * @return
     * @exception
     */ 
    public boolean setValue(String configFilePath,String configFileName,String key,Object value){
    	PropertyBean<?,?> obj = get(configFileName);
        if(Objects.isNull(obj)) {
            return getPropertyCachePool().put(configFileName,
                    new SinglePropertyBean(configFilePath,configFileName).load()).set(key, value);
        }
        synchronized(this) {
        	return obj.set(key, value);
        }
    }
    
    /**  
     * @param configFileName
     * @return
     * @exception
     */ 
    public boolean read(String configFileName) {
    	PropertyBean<?,?> obj = get(configFileName);
        return obj == null || obj.load() == null;
    }
    
    /**  
     * @param configFileName
     * @return
     * @exception
     */ 
    public boolean write(String configFileName) {
    	PropertyBean<?,?> obj = get(configFileName);
        return obj == null || obj.write() == null;
    }
    
    /**  
     * @param configurationFileName
     * @exception
     */ 
    public PropertyManager settingDefaultConfigurationName(String configurationFileName) {
        PropertyConfiguration.DEFAULT_PROPERTIES_FILE_NAME = configurationFileName;
        return this;
    }
    
}
